<!DOCTYPE html>
<html style="display: none;" lang="zh">
    <head>
    <meta charset="utf-8">
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.5.2 -->
    <script>
        window.materialVersion = "1.5.2"
        // Delete localstorage with these tags
        window.oldVersion = [
            'codestartv1',
            '1.3.4',
            '1.4.0',
            '1.4.0b1',
            '1.5.0'
        ]
    </script>

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">


    <link rel="dns-prefetch" href="https://cdn1.lncld.net"/>













    <!-- Meta & Info -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

    <!-- Title -->
    
    <title>
        
            jenkins使用教程 | 
        
        Selton Blog
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/header/Taurus.png">
    <link rel="icon" href="/img/favicon.png">

    <meta name="format-detection" content="telephone=no"/>
    <meta name="description" itemprop="description" content="">
    <meta name="keywords" content="docker使用入门教程,jenkins,ci,持续化集成,使用">
    <meta name="theme-color" content="#0097A7">

    <!-- Disable Fucking Bloody Baidu Tranformation -->
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import lsloader -->
    <script>(function(){window.lsloader={jsRunSequence:[],jsnamemap:{},cssnamemap:{}};lsloader.removeLS=function(a){try{localStorage.removeItem(a)}catch(b){}};lsloader.setLS=function(a,c){try{localStorage.setItem(a,c)}catch(b){}};lsloader.getLS=function(a){var c="";try{c=localStorage.getItem(a)}catch(b){c=""}return c};versionString="/*"+(window.materialVersion||"unknownVersion")+"*/";lsloader.clean=function(){try{var b=[];for(var a=0;a<localStorage.length;a++){b.push(localStorage.key(a))}b.forEach(function(e){var f=lsloader.getLS(e);if(window.oldVersion){var d=window.oldVersion.reduce(function(g,h){return g||f.indexOf("/*"+h+"*/")!==-1},false);if(d){lsloader.removeLS(e)}}})}catch(c){}};lsloader.clean();lsloader.load=function(f,a,b,d){if(typeof b==="boolean"){d=b;b=undefined}d=d||false;b=b||function(){};var e;e=this.getLS(f);if(e&&e.indexOf(versionString)===-1){this.removeLS(f);this.requestResource(f,a,b,d);return}if(e){var c=e.split(versionString)[0];if(c!=a){console.log("reload:"+a);this.removeLS(f);this.requestResource(f,a,b,d);return}e=e.split(versionString)[1];if(d){this.jsRunSequence.push({name:f,code:e});this.runjs(a,f,e)}else{document.getElementById(f).appendChild(document.createTextNode(e));b()}}else{this.requestResource(f,a,b,d)}};lsloader.requestResource=function(b,e,a,c){var d=this;if(c){this.iojs(e,b,function(h,f,g){d.setLS(f,h+versionString+g);d.runjs(h,f,g)})}else{this.iocss(e,b,function(f){document.getElementById(b).appendChild(document.createTextNode(f));d.setLS(b,e+versionString+f)},a)}};lsloader.iojs=function(d,b,g){var a=this;a.jsRunSequence.push({name:b,code:""});try{var f=new XMLHttpRequest();f.open("get",d,true);f.onreadystatechange=function(){if(f.readyState==4){if((f.status>=200&&f.status<300)||f.status==304){if(f.response!=""){g(d,b,f.response);return}}a.jsfallback(d,b)}};f.send(null)}catch(c){a.jsfallback(d,b)}};lsloader.iocss=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.iofonts=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.runjs=function(f,c,e){if(!!c&&!!e){for(var b in this.jsRunSequence){if(this.jsRunSequence[b].name==c){this.jsRunSequence[b].code=e}}}if(!!this.jsRunSequence[0]&&!!this.jsRunSequence[0].code&&this.jsRunSequence[0].status!="failed"){var a=document.createElement("script");a.appendChild(document.createTextNode(this.jsRunSequence[0].code));a.type="text/javascript";document.getElementsByTagName("head")[0].appendChild(a);this.jsRunSequence.shift();if(this.jsRunSequence.length>0){this.runjs()}}else{if(!!this.jsRunSequence[0]&&this.jsRunSequence[0].status=="failed"){var d=this;var a=document.createElement("script");a.src=this.jsRunSequence[0].path;a.type="text/javascript";this.jsRunSequence[0].status="loading";a.onload=function(){d.jsRunSequence.shift();if(d.jsRunSequence.length>0){d.runjs()}};document.body.appendChild(a)}}};lsloader.tagLoad=function(b,a){this.jsRunSequence.push({name:a,code:"",path:b,status:"failed"});this.runjs()};lsloader.jsfallback=function(c,b){if(!!this.jsnamemap[b]){return}else{this.jsnamemap[b]=b}for(var a in this.jsRunSequence){if(this.jsRunSequence[a].name==b){this.jsRunSequence[a].code="";this.jsRunSequence[a].status="failed";this.jsRunSequence[a].path=c}}this.runjs()};lsloader.cssfallback=function(e,c,b){if(!!this.cssnamemap[c]){return}else{this.cssnamemap[c]=1}var d=document.createElement("link");d.type="text/css";d.href=e;d.rel="stylesheet";d.onload=d.onerror=b;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(d,a)};lsloader.runInlineScript=function(c,b){var a=document.getElementById(b).innerText;this.jsRunSequence.push({name:c,code:a});this.runjs()}})();</script>

    <!-- Import queue -->
    <script>function Queue(){this.dataStore=[];this.offer=b;this.poll=d;this.execNext=a;this.debug=false;this.startDebug=c;function b(e){if(this.debug){console.log("Offered a Queued Function.")}if(typeof e==="function"){this.dataStore.push(e)}else{console.log("You must offer a function.")}}function d(){if(this.debug){console.log("Polled a Queued Function.")}return this.dataStore.shift()}function a(){var e=this.poll();if(e!==undefined){if(this.debug){console.log("Run a Queued Function.")}e()}}function c(){this.debug=true}}var queue=new Queue();</script>

    <!-- Import CSS -->
    
        <style id="material_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_css","/css/material.min.css?Z7a72R1E4SxzBKR/WGctOA==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
        <style id="style_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("style_css","/css/style.min.css?MKetZV3cUTfDxvMffaOezg==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>

        

    

    

    <!-- Config CSS -->

<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    overflow-x: hidden !important;
  }
  
  code {
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body{
        background-color: #F5F5F5;
      }

      /* blog_info bottom background */
      #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text{
        background-color: #fff;
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


<!-- Import Font -->
<!-- Import Roboto -->

    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">


<!-- Import Material Icons -->


    <style id="material_icons"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_icons","/css/material-icons.css?pqhB/Rd/ab0H2+kZp0RDmw==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>




    <!-- Import jQuery -->
    
        <script>lsloader.load("jq_js","/js/jquery.min.js?qcusAULNeBksqffqUM2+Ig==", true)</script>
    

    <!-- WebAPP Icons -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="Selton Blog">
    <meta name="msapplication-starturl" content="https://selton.cn/jenkinsUse.html">
    <meta name="msapplication-navbutton-color" content="#0097A7">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="Selton Blog">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Site Verification -->
    
    

    <!-- RSS -->
    

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="https://selton.cn/jenkinsUse.html">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="jenkins使用教程 | Selton Blog">
    <meta property="og:image" content="/img/favicon.png">
    <meta property="og:description" content="">
    <meta property="og:article:tag" content="jenkins"> <meta property="og:article:tag" content="ci"> <meta property="og:article:tag" content="持续化集成"> <meta property="og:article:tag" content="使用"> 

    
        <meta property="article:published_time" content="Tue Jan 29 2019 09:38:53 GMT+0800">
        <meta property="article:modified_time" content="Wed Jan 30 2019 18:18:55 GMT+0800">
    

    <!-- The Twitter Card protocol -->
    <meta name="twitter:card" content="summary_large_image">

    <!-- Add canonical link for SEO -->
    
        <link rel="canonical" href="https://selton.cn/jenkinsUse.html" />
    

    <!-- Structured-data for SEO -->
    
        


<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": "https://selton.cn/jenkinsUse.html",
    "headline": "jenkins使用教程",
    "datePublished": "Tue Jan 29 2019 09:38:53 GMT+0800",
    "dateModified": "Wed Jan 30 2019 18:18:55 GMT+0800",
    "author": {
        "@type": "Person",
        "name": "Selton",
        "image": {
            "@type": "ImageObject",
            "url": "/img/zh.jpg"
        },
        "description": "你的痛苦俯仰皆是,你的惆怅人皆有之."
    },
    "publisher": {
        "@type": "Organization",
        "name": "Selton Blog",
        "logo": {
            "@type":"ImageObject",
            "url": "/img/favicon.png"
        }
    },
    "keywords": ",jenkins,ci,持续化集成,使用docker使用入门教程",
    "description": "",
}
</script>


    

    <!-- Analytics -->
    
    
        <script>
    var _hmt = _hmt || [];
    (function() {var hm = document.createElement('script');
    hm.src = 'https://hm.baidu.com/hm.js?be5a31edaf6d767c1c2470bc9337ac65';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(hm, s);
    })();
</script>
    
    

    <!-- Custom Head -->
    

</head>


    
        <body id="scheme-Paradox" class="lazy">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->


    <!-- Left aligned menu below button -->
    
    
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#快速上手"><span class="post-toc-number">1.</span> <span class="post-toc-text">快速上手</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#起源"><span class="post-toc-number">2.</span> <span class="post-toc-text">起源</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#为什么选择jenkins"><span class="post-toc-number">3.</span> <span class="post-toc-text">为什么选择jenkins</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#结论"><span class="post-toc-number">3.1.</span> <span class="post-toc-text">结论</span></a></li></ol></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#使用"><span class="post-toc-number">4.</span> <span class="post-toc-text">使用</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#拉取远程git库代码到本地"><span class="post-toc-number">4.1.</span> <span class="post-toc-text">拉取远程git库代码到本地</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#使用编译工具本地编译拉取到的代码"><span class="post-toc-number">4.2.</span> <span class="post-toc-text">使用编译工具本地编译拉取到的代码</span></a></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#将编译的结果部署到指定的机器上"><span class="post-toc-number">4.3.</span> <span class="post-toc-text">将编译的结果部署到指定的机器上</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#建立从机节点"><span class="post-toc-number">4.3.1.</span> <span class="post-toc-text">建立从机节点</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#在节点上部署服务"><span class="post-toc-number">4.3.2.</span> <span class="post-toc-text">在节点上部署服务</span></a></li></ol></li></ol></li></ol>
    </ul>
    




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        
            <!-- Random Thumbnail -->
            <div class="post_thumbnail-random mdl-card__media mdl-color-text--grey-50">
            <script type="text/ls-javascript" id="post-thumbnail-script">
    var randomNum = Math.floor(Math.random() * 19 + 1);

    $('.post_thumbnail-random').attr('data-original', '/img/random/material-' + randomNum + '.png');
    $('.post_thumbnail-random').addClass('lazy');
</script>

        
    
            <p class="article-headline-p">
                jenkins使用教程
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/zh.jpg" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>Selton</strong>
        <span>1月 29, 2019</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        <a class="post_tag-link" href="/tags/ci/">ci</a></li><li class="mdl-menu__item"><a class="post_tag-link" href="/tags/jenkins/">jenkins</a></li><li class="mdl-menu__item"><a class="post_tag-link" href="/tags/使用/">使用</a></li><li class="mdl-menu__item"><a class="post_tag-link" href="/tags/持续化集成/">持续化集成</a>
    </ul>
    

    <!-- Share -->
    
        <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    
    <!-- Leancloud Views -->
        <a class="post_share-link" href="#">
            <li class="mdl-menu__item">
                <span id="/jenkinsUse.html" class="leancloud-views_num" data-flag-title="jenkins使用教程">
     &nbsp;浏览量
</span>

            </li>
        </a>
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=jenkins使用教程&url=https://selton.cn/jenkinsUse.html&pic=https://selton.cn/img/header/Taurus.png&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=jenkins使用教程&url=https://selton.cn/jenkinsUse.html&via=Selton" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=https://selton.cn/jenkinsUse.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=https://selton.cn/jenkinsUse.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

    
</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <p>Build great things at any scale.</p>
<h1 id="快速上手"><a href="#快速上手" class="headerlink" title="快速上手"></a>快速上手</h1><ol>
<li><a href="https://selton.cn/jenkinsInstall.html">安装jenkins</a></li>
<li><a href="#使用">使用jenkins</a></li>
</ol>
<h1 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h1><p>一个项目比较完整的生命周期该是怎样的?</p>
<p>由开发的coding阶段和coding阶段的质量测试,再到多次发布投入使用阶段</p>
<p>而现代化的测试阶段并不是从coding结束后开始,而是和coding同步进行的,今天上午coding完成一个功能,下午就要投入测试</p>
<p>如何测试呢,也就是将开发者完成的代码,拉取到服务器A(一般是linux)上,按照开发者的部署文档搭建各种依赖服务(可能是mysql,redis,kafka等等),然后运行代码编译后的文件或者是运行脚本</p>
<p>如果我们测试得出开发者今天完成的新功能存在问题,我们需要提出bug,然后开发者解决这个bug,解决完之后呢?</p>
<p>如果开发者在bug解决文档中没有说明是依赖服务出现了问题导致的这个bug,那么A机器上的依赖服务我们是不用重新搭建的,无非就是启动和停止.</p>
<p>变化的往往都是开发者的功能的代码部分.对于java coder,一般是将开发者在git的指定分支上的代码pull下来之后编译打包,然后替换掉A机器上的编译后的包,重启服务,继续测试</p>
<p>每当需求发生变化,功能需要改进,bug等等问题的时候,代码就会发成变化,而将这种变化需要我们在测试机器上得以体现,可能就是替换代码包之类的,这个过程重复而且繁杂,也容易出现部署失误,这种需求背景下产生了自动化持续构建的概念.</p>
<p>而jenkins正是贯彻和发扬了这一理念的持续构建工具</p>
<p>The leading open source automation server, Jenkins provides hundreds of plugins to support building, deploying and automating any project.</p>
<blockquote>
<p>领先的开源自动化服务,jenkins中提供了众多的插件以支持使用自动化的方式构建和发布任何工程.</p>
</blockquote>
<p>本文作者同大家一起开始步入jenkins的镜像世界,一步一步,深入jenkins,从入门到精通,从使用到理解掌握</p>
<h1 id="为什么选择jenkins"><a href="#为什么选择jenkins" class="headerlink" title="为什么选择jenkins"></a>为什么选择jenkins</h1><p>既然都是为了实现自动化持续构建,难道就jenkins这一个选择吗</p>
<p>通常我会使用百度指数,在涉足一个新的领域的时候帮助我了解这个领域哪些将会是趋势,哪些只是残留</p>
<blockquote>
<p>百度指数只能反映国内的一部分情况,以后会加入google指数来反映国外的情况.</p>
</blockquote>
<p><strong>hudson/jenkins</strong></p>
<p>hudson是jenkins的前称</p>
<p>jenkins 2012-2019百度搜索指数趋势图</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130161922811-1138705890.png" alt=""></p>
<p>hudson的趋势数量级在百,忽略不计</p>
<p><strong>TeamCity</strong><br>TeamCity是jet大脑的出品,百度搜索指数还未收录</p>
<p><strong>Travis</strong></p>
<p>Travis CI是最老的托管解决方案之一</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130161939253-1247877939.png" alt=""></p>
<p><strong>其他</strong></p>
<p>其他有如gitlab ci,bamboo由于存在关键词意义重叠的情况,目前还没有想到比较好的解决方案,这次不加入比较.</p>
<h2 id="结论"><a href="#结论" class="headerlink" title="结论"></a>结论</h2><p>从上面的趋势图中无论是基数还是趋势,jenkins的学习性价比对比travis要高许多.</p>
<blockquote>
<p>当你选择了一种语言，意味着你还选择了一组技术、一个社区</p>
</blockquote>
<p>从二次开发的角度来看,jenkins开源,而且使用的语言是java,使用的框架为spring,两者分别为国内语言社区和框架社区中的顶级社区,发展的特别的好.</p>
<h1 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h1><p>我们将使用jenkins完成三个最为重要和基础的功能</p>
<ol>
<li><a href="#拉取远程git库代码到本地">拉取远程git库代码到本地</a></li>
<li><a href="#使用编译工具本地编译拉取到的代码">使用编译工具本地编译拉取到的代码</a></li>
<li><a href="#将编译的结果部署到指定的机器上">将编译的结果部署到指定的机器上</a></li>
</ol>
<h2 id="拉取远程git库代码到本地"><a href="#拉取远程git库代码到本地" class="headerlink" title="拉取远程git库代码到本地"></a>拉取远程git库代码到本地</h2><p>主界面是这样的</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162708159-687800673.png" alt=""></p>
<p>为了规整,我们可以先创建一个文件夹(目录)</p>
<p>点击new任务,出现</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162741637-477047355.png" alt=""></p>
<p>点击文件夹,然后在输入框中输入文件夹的名字,后点击ok后进入了文件夹属性配置界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162756136-596789681.png" alt=""></p>
<p>不管这个界面,点击左上方的jenkins图标回到jenkins主页</p>
<p>发现此时多了一个文件夹</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162854712-1706518071.png" alt=""></p>
<p>点击进入</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162916631-1369609470.png" alt=""></p>
<p>点左上方的New item<br>和之前的new 任务页面类似</p>
<p>点击构建一个自由风格的软件项目<br>在输入框输入这个自动化任务的名称</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162937354-399047722.png" alt=""></p>
<p>点ok之后进入配置界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130162949495-1874513651.png" alt=""></p>
<p> 在这个配置界面下拉到Source Code Management,点击选中git</p>
<p>在Repository URL中输入需要maven构建的代码的仓库地址</p>
<p>Branch Specifier中输入需要构建的分支的名称,<em>/master表示构建分支名为master,</em>/你的分支的名字</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163000976-56138290.png" alt=""></p>
<p>接下来需要认证这个仓库,点击Credentials右边的add</p>
<p>出现了下拉,一个是jenkins,一个是我们的文件夹名称(githubTasks)<br>我们选择文件夹名称</p>
<p>在弹出的窗口中类型选择为Username with password<br>然后输入你的登录到git仓库的用户名和密码</p>
<p>然后点击添加,在Credentials的无 下拉,有我们刚刚添加的账户</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163011824-707178391.png" alt=""></p>
<p>点击最下方的Save,完成这个自动化构建任务的第一步,拉取远程git库的代码到本地(jenkins所在服务器,docker的话就是docker的容器内部)</p>
<p>我们可以看到是否拉取成功,回到这个界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163022088-407555398.png" alt=""></p>
<p>点击进入<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163034371-1565014688.png" alt=""></p>
<p>坐下方的Build History里面有一个 #1<br>点击进入</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163044785-1761555859.png" alt=""></p>
<p>点击左侧栏的Console Output进入</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163054563-2016123514.png" alt=""></p>
<p>注意这个位置是导航栏,这里我们可以随意跳转到主界面,文件夹界面或者是任务界面<br>jenkins是主界面,githubTasks是文件夹<br>compileGithub是任务界面<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163105488-1756488567.png" alt=""></p>
<p>我们点击compileGithub进入任务界面<br>点击workSpace<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163114828-648031864.png" alt=""></p>
<p>进入到了这个界面,里面可以看到我们的拉取的代码</p>
<p>可以看到这个界面的标题<strong>节点master上的工作空间</strong>,在之后的将代码编译后的成品发布到任意指定机器上的那部份,我会对节点,加以解释,现在这个节点master值得就是jenkins所在的这台机器.</p>
<p>上面的工作完成了将代码从远程git仓库拉取到本地,接下来需要在本地编译这些代码</p>
<p><strong>引申</strong></p>
<p>如果我经常需要拉取不同的分支的代码,也就是分支这个字符串,是经常需要改变的,难道我每次都要修改任务配置中的Branch Specifier吗?</p>
<p>让我们返回到jenkins主页,这儿需要加入一个git参数动态化的插件</p>
<p>主页中点击系统设置,点击插件管理<br>然后点击Available<br>filter 中输入:git parameter</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163128934-1777259238.png" alt=""></p>
<p>筛选出来的插件中勾选 Git Parameter<br>点击install without restart之后</p>
<p>等到Git Parameter 图标为 Success即ok<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163143992-1000788871.png" alt=""></p>
<p>点击Go Back to the top page,回到首页</p>
<p>点击导航栏任务compileGithubCode,没有的话先进入文件夹githubTasks,然后从这里点击compileGithubCode进入任务<br>点击左侧的Configure<br>进入到了任务的配置界面</p>
<p>找到并勾选参数化构建过程</p>
<p>下拉选择Git Parameter</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163157474-9247284.png" alt=""></p>
<p>在name中为这个分支字符串变量起个名字,以后用$获取</p>
<p>Parameter Type下拉选择branch</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163211008-1077802460.png" alt=""></p>
<p>点击左下角save</p>
<p>这时候我们发现任务左侧边栏的开始构建没有了,取而代之的是Build With Parameters</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163222595-1153099301.png" alt=""></p>
<p>点击Build With Parameters转到界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163233466-1052886318.png" alt=""></p>
<p>这个列表会罗列出该git仓库的所有分支,我们选择点击选择一个,然后点Build就好了</p>
<h2 id="使用编译工具本地编译拉取到的代码"><a href="#使用编译工具本地编译拉取到的代码" class="headerlink" title="使用编译工具本地编译拉取到的代码"></a>使用编译工具本地编译拉取到的代码</h2><p>得到了远程库的代码,现在要在本地编译这些代码</p>
<p>java coder的话,使用maven编译打包</p>
<p>这个时候就要添加maven这一全局工具了</p>
<blockquote>
<p>注意: 接下来是自动的在jenkins机器上安装了一个maven,但是如果你原本项目的maven编译依赖着.setting.xml中配置的maven私服或者是proxy代理的话,还需要别的操作,最粗暴不过进入到jenkins所在机器(这里是docker的容器内部),找到并配置maven的setting.xml</p>
</blockquote>
<p>导航栏点击jenkins进入到主界面</p>
<p>点击左侧系统管理进入到了<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163247252-360527062.png" alt=""></p>
<p>点击全局工具配置,然后下拉到<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163257203-844798005.png" alt=""></p>
<p>点击add maven<br>在name中输入你给它起得名字,这里起了名字maven36来标识他是3.6.0版本<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163308481-1694570565.png" alt=""></p>
<p>点击左下角的Save</p>
<p>然后回到了主界面,点击jenkins,点击文件夹githubTasks,点击任务compileGithubCode</p>
<p>点击左侧Configure</p>
<p>其实可以注意到,这里也有导航栏<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163324397-1687119342.png" alt=""></p>
<p>我们点击Build<br>然后点击add build step</p>
<p>选择 执行顶层Maven目标<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163333957-2078542157.png" alt=""></p>
<p>出来的界面中<br>maven version 中下拉选择我们上一步在系统设置的全局工具配置中起得maven名称<br>Goals部分大部分都是clean install,clean package之类的maven编译命令<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163344384-477674952.png" alt=""></p>
<p>点击左下方save,ok</p>
<p>回到任务compileGithub界面,点击左侧立即构建</p>
<p>看到了左下方build中标志着任务正在进行中的闪烁的图标<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163355606-477946037.png" alt=""></p>
<p>点击这个#3,进入到日志界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163406229-235559823.png" alt=""></p>
<p>我们在系统设置的全局工具配置中配置了如何下载maven等,但是实际上它是类似于单例模式,在第一次运行的时候初始化,以后都能使用</p>
<p>由于没有配置中央仓库为国内maven镜像库,而且是maven第一次构建,所以我这里构建的特别慢,花了将近15min</p>
<p>构建完成后的日志<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163417867-1720886962.png" alt=""></p>
<p>构建完成之后我们进入任务界面compileGithubCode</p>
<p>点击workspace<br>进入到jar产生的target目录,发现成功编译得到了jar文件<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163427874-1799539047.png" alt=""></p>
<p>但是以后比如别的人想从网页上下载这个编译好的jar,能不能直接从页面上下载下来,当然可以,点击这个jar就会下载下来</p>
<p>但是我们要明白这个任务的目的是什么,其实就是得到这个编译后的成果,过程怎么样是没人关心的,也就是这个任务应该对外完美暴露它的成功,也就是这个jar,不仅要方便大家从页面上下载这个jar,还有后面的任务可能会从这个任务上拿取jar</p>
<p>需要添加构建后操作,回到这个任务的配置页面,找到Post-build Actions,下拉选择归档成品</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163439896-223031997.png" alt=""></p>
<p>在Files to archive中填写需要暴露的jar的位置</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163449265-493511069.png" alt=""></p>
<p>位置是可以从任务的工作空间中看到的</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163502429-858853490.png" alt=""></p>
<p>然后我们回到任务主页,点击开始Build with parameter,选择分支,build</p>
<p>build成功后,我们进入该任务的主页</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163511997-1841027637.png" alt=""></p>
<p>发现多了一个Last Successful Artifacts,这样就可以很方便的从页面上下载这个jar,而不用担心忘了编译后的成果在什么文件夹位置的情况.</p>
<blockquote>
<p>注意: 这一步是必备的,不然下面的发布的任务会无法从这个任务中自动化的获取jar</p>
</blockquote>
<p>至此完成了本地编译从远程库pull下来的代码的阶段.</p>
<h2 id="将编译的结果部署到指定的机器上"><a href="#将编译的结果部署到指定的机器上" class="headerlink" title="将编译的结果部署到指定的机器上"></a>将编译的结果部署到指定的机器上</h2><p>接下来我们需要理解jenkins中节点的概念</p>
<p>jenkins安装在一台机器，所有的jobs都在这台机器上运行，如果超过太多jobs去运行，会形成等待，节点存在就是解决这个问题提高效率，安装jenkins的机器称为master机，而其它机器就属于master的分支，成为slave；而要利用其它机器用执行jenkins的jobs，则需要一些配置，形成两台机器互通，当然下面的例子你用本机当做slave也是可以的</p>
<blockquote>
<p>从机节点的建立意味着这台从机就是master的一个复刻,master能执行的任务它都能干(master的向从机发送命令这一功能除外)</p>
</blockquote>
<p>也就是完整的发布过程是这样的,master机器访问从机B,向B发送 拉取代码到本地 的命令,master机器做的仅仅是发送命令,然后干别的,等到B将远程代码pull到了B的本地</p>
<p>本地编译代码的过程也是如此</p>
<p>而现在我们就是需要从机得到代码,编译,然后在本地执行启动服务的脚,如果是tomcat应用的话(外置),可能是将编译后的war放入webapps下,然后启动tomcat的startup.sh</p>
<p>那我们先完成第一步,建立从机节点,说白了,就是我作为master,怎么访问从机,用户名加密码也好,ssh认证也好</p>
<h3 id="建立从机节点"><a href="#建立从机节点" class="headerlink" title="建立从机节点"></a>建立从机节点</h3><p>为了方便用户管理,我们最好不要使用使得master访问从机的root用户,比如这里,我们使用用户jenkins用户</p>
<p>连接到一台从机(root用户)</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">groupadd jenkins</span><br><span class="line">useradd jenkins -g jenkins</span><br><span class="line">passwd jenkins</span><br></pre></td></tr></table></figure>
<p>接下来需要输入jenkins用户的密码,要求比较严格,密码要求为至少8位的非简单字符串</p>
<p>密码定位kinsjen0</p>
<p>然后我们切换到jenkins用户</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">su - jenkins</span><br><span class="line">pwd</span><br></pre></td></tr></table></figure>
<p>jenkins的~目录在/home/jenkins</p>
<p>因为jenkins是用java写的后台,需要注意这台从机机器需要有java环境<br><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">which java</span><br></pre></td></tr></table></figure></p>
<p>得到的路径地址会在后面配置节点信息的时候用到</p>
<p>接下来我们进入jenkins主页,点击左侧系统管理,然后下拉找到节点管理,点击之后是这样的</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163545112-1109057902.png" alt=""></p>
<p>注意到已经有了一个节点master,就是我们安装jenkins的机器,我们点击左边的New Node</p>
<p>在输入框中输入我们给这个节点机器起得名字<br>并勾选固定节点</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163555078-969038181.png" alt=""></p>
<blockquote>
<p>切记这里的节点名不能包含中文字符,不然之后的操作会无法识别这个节点,如果已经发现了问题,可以在节点的设置中修改名称.</p>
</blockquote>
<p>点击ok后展开页面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163605862-1861701622.png" alt=""></p>
<p>Remote root directory中输入你的从机的用户的~地址<br>也就是我们的从机的jenkins用户的~,/home/jenkins</p>
<p>然后下拉Usage,切换到 只允许绑定到这台机器的job,Host输入这台节点的ip</p>
<blockquote>
<p>注意,要确保在master机器上能够ping通这个ip</p>
</blockquote>
<p>然后下拉Host Key Verification Strategy,选择Manually trusted key Verification Strategy</p>
<p>随后点击Credentials右侧的add,点击下拉出现的jenkins,出现界面</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163618584-607767924.png" alt=""></p>
<p>在username中输入节点机器的用户名jenkins,在password中输入这个用户的密码,然后点击添加</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163628883-1906810058.png" alt=""></p>
<p>随后在Credentials的下拉中选择我们刚刚添加的用户密码信息</p>
<p>点击Launch method右下方的Advanced,这里唯一要做的是填写javapath,也就是我们在节点机器上新建用户的时候说道的which java得到的java路径</p>
<blockquote>
<p>注意: 如果ssh端口暴露的是36000,记得这里修改port的22为36000,不然启动日志会报错</p>
</blockquote>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163638945-294571163.png" alt=""></p>
<p>点击左下方Save完成节点的配置.此时跳转到了节点管理界面.</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163648509-1752007809.png" alt=""></p>
<p>可以看到此时的节点处于未启动状态,因为启动需要一段时间,主机会将服务的相关代码copy到从机的/home/jenkins下</p>
<p>可以点击节点 测试机器1jenkins用户,进入后的界面点击启动;也可以稍等一会儿,它会自动去启动,启动成功后可以看到这个节点管理界面发生了变化,这样表示成功建立了节点</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163659813-1108639380.png" alt=""></p>
<p>至此完成了从机节点的配置.</p>
<blockquote>
<p>提示: 可以登录到从机机器上,切到jenkins用户,切换到~目录下,ls后可以看到名为remoting.jar和remoting文件夹</p>
</blockquote>
<h3 id="在节点上部署服务"><a href="#在节点上部署服务" class="headerlink" title="在节点上部署服务"></a>在节点上部署服务</h3><p>接下来让我们收货最终的成果,在节点机器上发布应用</p>
<p>这时候我们需要什么?</p>
<p>我们需要在从机机器上运行我们的代码编译完成的jar</p>
<p>那么第一步就是取得我们的jar</p>
<p>如何取得我们的代码的jar,我们已经在任务compileGithub中得到了远程代码,并编译了它,现在我们需要它的编译结果</p>
<p>有这么一个插件需要我们添加,来帮助我们在一个新的任务中拉取另一个任务的编译结果</p>
<p>回到jenkins首页,左侧系统管理,之后点插件管理,filter中输入:Copy Arti</p>
<p>勾选筛选出来的插件Copy Artifact</p>
<p>点击install without restart</p>
<p>Copy Artifact变为success之后</p>
<p>点击Go Back to the top page,完成插件的添加.</p>
<p>回到jenkins主页,进入githubTasks文件夹,点击左侧New Item,输入任务名称,比如deployMyCode,然后选择构建一个自由风格的软件项目,点OK</p>
<p>勾选Restrict where this project can be run,Label Expression中输入我们之前新建的节点的名字,输入了MachineTest1就已经有了提示,选中它</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163713646-2004475844.png" alt=""></p>
<p>这样就相当于是会让这个机器执行发布任务</p>
<p>接下来我们获取之前的任务构建的jar</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163723515-1197148208.png" alt=""></p>
<p>然后在Project name中输入我们之前的拉取代码并本地编译的任务名称 compileGitHubCode,</p>
<p>Artifacts to copy中输入vertx-api/target/*.jar,这个就是我们的任务compileGitHubCode执行完后在工作空间中能找到的jar的位置.</p>
<blockquote>
<p>提示: 这个在前面提到了<a href="#使用编译工具本地编译拉取到的代码">编译代码厚的保存构建生成物操作</a></p>
</blockquote>
<p>Target directory中输入packages</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163733708-236648032.png" alt=""></p>
<p>之后我们创建一个shell</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163746261-1293541157.png" alt=""></p>
<blockquote>
<p>注意顺序,这个添加的shell应该在Copy artifacts from another project的下面</p>
</blockquote>
<p>按道理我们应该在这个shell脚本中执行我们获得的jar,完成类似这样的发布任务的,但是为了熟悉一下这个脚本的执行环境,我们先运行一个简单的脚本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span>!/bin/bash</span><br><span class="line"></span><br><span class="line">deploy_testMachine() &#123;</span><br><span class="line">    touch test.log</span><br><span class="line">&#125;</span><br><span class="line">deploy_testMachine</span><br></pre></td></tr></table></figure>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163801937-131583629.png" alt=""></p>
<p>然后点击左下方的Save,回到了任务的主页面,我们点击左侧栏的立即构建</p>
<p>点击左下方的#5</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163811547-211056341.png" alt=""></p>
<p>然后点击左侧的Console Output</p>
<p><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130163821696-1567899173.png" alt=""></p>
<p>可以从日志中发现一些端倪</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Building remotely on MachineTest1UserJenkins in workspace /home/jenkins/workspace/githubTasks/deployMyCode</span><br></pre></td></tr></table></figure>
<p>也就是我们经常说的任务的工作空间实际是:</p>
<p>/home/jenkins也就是我们的节点用户</p>
<p>/workspace是我们的所有的工作空间的最上级</p>
<p>/githubTasks我们之前的文件夹</p>
<p>/deployMyCode是我们的这次任务</p>
<p>切入到/home/jenkins/workspace/githubTasks/deployMyCode</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">ls</span><br><span class="line">packages  test.log</span><br><span class="line"></span><br><span class="line">cd packages</span><br><span class="line">ls</span><br><span class="line">vertx-api</span><br><span class="line"></span><br><span class="line">cd vertx-api</span><br><span class="line">ls</span><br><span class="line">target</span><br><span class="line"></span><br><span class="line">cd target</span><br><span class="line">ls</span><br><span class="line">vertx-api-1.0.0.jar</span><br></pre></td></tr></table></figure>
<p>这样我们就明白了,这个脚本的执行目录在/home/jenkins/workspace/githubTasks/deployMyCode下,也就是我们的脚本实际上是在这个目录下被执行的</p>
<p>之后我们回到这个任务的配置界面,将我们的脚本修改为</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#</span>!/bin/bash</span><br><span class="line"></span><br><span class="line">deploy_testMachine() &#123;</span><br><span class="line">    java -jar ./packages/*.jar</span><br><span class="line">&#125;</span><br><span class="line">deploy_testMachine</span><br></pre></td></tr></table></figure>
<p>然后回到任务主页,立即构建,即可完成类似服务的发布这种</p>
<p>如果你需要每次删除上次残留在节点中的旧的代码,需要进入到任务的配置,在Build Environment下勾选Delete workspace before build starts即可<br><img src="https://img2018.cnblogs.com/blog/1394862/201901/1394862-20190130181808424-564716824.png" alt=""></p>
<p>至此完成从编译产物到产物发布的过程</p>

        
                <blockquote style="margin: 2em 0 0;padding: 0.5em 1em;border-left: 3px solid #F44336;background-color: #F5F5F5;list-style: none;">
                    <p><strong>
                         
                            转载无须注明出处,就说是自己做的(＝^ω^＝)
                        </strong>
                        <br>
                        <strong>本文链接：</strong><a href="https://selton.cn/jenkinsUse.html">https://selton.cn/jenkinsUse.html</a>
                    </p>
                </blockquote>
        
    

    
</div>


                

                <!-- Post Comments -->
                
                    
    <div id="comment" style='padding:10px;' class="vcomment"></div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script>
    var GUEST_INFO = ['nick','mail','link'];
    var guest_info = 'nick,mail,link'.split(',').filter(function(item){
        return GUEST_INFO.indexOf(item) > -1
    });
    var notify = 'false' == true;
    var verify = 'false' == true;
    new Valine({
        el: '.vcomment',
        notify: notify,
        verify: verify,
        appId: "bXfVz4s0H1YbOPe8VtjgDWHp-gzGzoHsz",
        appKey: "OJQYQlOupQ3r08BB7AVFOV8o",
        placeholder: "Thank you for reading!",
        pageSize:'10',
        avatar:'identicon',
        lang:'zh-cn'
    });
</script>

                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/lombok.html" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/Primary-SortingAlgorithms1-SortRule.html" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.png);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/zh.jpg" alt="Selton's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        seltonzyf@gmail.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="#" target="_blank" title="Email Me">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        Email Me
                    </a>
                </li>
            
                <li>
                    <a href="https://www.cnblogs.com/selton/" target="_blank" title="博客园">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        博客园
                    </a>
                </li>
            
                <li>
                    <a href="https://www.zhihu.com/people/seltonzyf" target="_blank" title="知乎">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        知乎
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2019/01/">一月 2019<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/10/">十月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/09/">九月 2018<span class="sidebar_archives-count">4</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">chrome_reader_mode</i>
                
                分类
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
                <li>
                
            </ul>
        </li>
        
    

    <!-- Pages  -->
    

    <!-- Article Number  -->
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->

    <a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
            主题 - Material
            <span class="sidebar-badge badge-circle">i</span>
        </div>
    </a>


<!-- Help & Support -->
<!--

    <a href="mailto:hiviosey@gmail.com" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        sidebar.help
        <span class="mdl-button__ripple-container">
          <span class="mdl-ripple"></span>
        </span>
      </div>
    </a>

-->

<!-- Feedback -->
<!--

    <a href="https://github.com/viosey/hexo-theme-material/issues" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        sidebar.feedback
        <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

<!-- About Theme -->
<!--

    <a href="https://blog.viosey.com/index.php/Material.html" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
             sidebar.about_theme
            <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div id="back-to-top" class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    

    <!-- Facebook -->
    

    <!-- Google + -->
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/seltonGitHub" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-github">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    
        <a href="https://www.zhihu.com/people/seltonzyf" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-zhihu">
                <span class="visuallyhidden">Zhihu</span>
            </button><!--
     --></a>
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    
    
    <!-- V2EX -->
    
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©&nbsp;2018&nbsp;-<script type="text/javascript">var fd = new Date();document.write("&nbsp;" + fd.getFullYear() + "&nbsp;");</script>Selton Blog
            
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank" class="footer-develop-a">Hexo</a></div>
                <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material" target="_blank" class="footer-develop-a">Material</a></div>
            </div>
        </div>
    
</footer>


                    <!-- Import JS File -->

    <script>lsloader.load("lazyload_js","/js/lazyload.min.js?1BcfzuNXqV+ntF6gq+5X3Q==", true)</script>



    <script>lsloader.load("js_js","/js/js.min.js?V/53wGualMuiPM3xoetD5Q==", true)</script>



    <script>lsloader.load("np_js","/js/nprogress.js?pl3Qhb9lvqR1FlyLUna1Yw==", true)</script>


<script type="text/ls-javascript" id="NProgress-script">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>





    <!-- Leancloud -->
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>
        AV.initialize('mKudodOwRnXiriu0X9QTbrOR-gzGzoHsz', '7p9Cqu1Elj8CixvXFtn9Flrj');
    </script>
    <script type="text/ls-javascript" id="leancloud-views-script">
    function showTime(Counter) {
        var query = new AV.Query(Counter);
        $('.leancloud-views_num').each(function() {
            var url = $(this).attr('id').trim();
            query.equalTo('url', url);
            query.find({
                success: function(results) {
                    if (results.length === 0) {
                        var content = '0 ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                        return;
                    }
                    for (var i = 0; i < results.length; i++) {
                        var object = results[i];
                        var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    }
                },
                error: function(object, error) {
                    console.log('Error: ' + error.code + ' ' + error.message);
                }
            });
        });
    }

    function addCount(Counter) {
      var Counter = AV.Object.extend('Counter');
      url = $('.leancloud-views_num').attr('id').trim();
      title = $('.leancloud-views_num').attr('data-flag-title').trim();
      var query = new AV.Query(Counter);
      query.equalTo('url', url);
      query.find({
          success: function(results) {
            if (results.length > 0) {
                var counter = results[0];
                counter.fetchWhenSave(true);
                counter.increment('time');
                counter.save(null, {
                    success: function(counter) {
                        var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    },
                    error: function(counter, error) {
                        console.log('Failed to save Visitor num, with error message: ' + error.message);
                    }
                });
            } else {
              var newcounter = new Counter();
              newcounter.set('title', title);
              newcounter.set('url', url);
              newcounter.set('time', 1);
              newcounter.save(null, {
                  success: function(newcounter) {
                      console.log('newcounter.get(\'time\')='+newcounter.get('time'));
                      var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
                      $(document.getElementById(url)).text(content);
                  },
                  error: function(newcounter, error) {
                      console.log('Failed to create');
                  }
              });
            }
        },
        error: function(error) {
            console.log('Error:' + error.code + ' ' + error.message);
        }
      });
    }
    $(function() {
        var Counter = AV.Object.extend('Counter');
        if ($('.leancloud-views_num').length === 1) {
            addCount(Counter);
        } else if ($('.post-title-link').length > 1) {
            showTime(Counter);
        }
    });
</script>






   





<!-- UC Browser Compatible -->
<script>
	var agent = navigator.userAgent.toLowerCase();
	if(agent.indexOf('ucbrowser')>0) {
		document.write('<link rel="stylesheet" href="/css/uc.css">');
	   alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
	}
</script>

<!-- Import prettify js  -->


    
        <script>lsloader.load("hanabi","/js/hanabi-browser-bundle.js?Pki5+pzkluqu53g+ouMWpA==", true)</script>
    


<!-- Window Load -->
<!-- add class for prettify -->
<script type="text/ls-javascript" id="window-load">
    $(window).on('load', function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });

    
    
        
        
        HanabiBrowser.start('pre code',true);
    
</script>

<!-- MathJax Load-->


<!-- Bing Background -->


<script type="text/ls-javascript" id="lazy-load">
    // Offer LazyLoad
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    // Start Queue
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

<!-- Custom Footer -->



<script>
    (function(){
        var scriptList = document.querySelectorAll('script[type="text/ls-javascript"]')

        for (var i = 0; i < scriptList.length; ++i) {
            var item = scriptList[i];
            lsloader.runInlineScript(item.id,item.id);
        }
    })()
console.log('\n %c © Material Theme | Version: 1.5.2 | https://github.com/viosey/hexo-theme-material %c \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-left-radius:5px;border-bottom-left-radius:5px;', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-right-radius:5px;border-bottom-right-radius:5px;');
</script>

                </main>
            </div>
        </body>
    
</html>
